/*
 *  Copyright (C) 2009  Peter Kist & Jan Ripke
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __entity_behaviorfactory_h
#define __entity_behaviorfactory_h

#include <string>

#include <boost/unordered_map.hpp>

#include <Core/Entity/Behavior.h>

namespace galaxy {
	namespace entity {

		/** This class controls construction of behavior objects from registed factory objects.
		* In effect the registered objects will 'clone' a new instance but without copying the
		* factory's attribute values into the new object .
		*/
		class BehaviorFactory
		{
			/** shorthand for behavior hash class type */
			typedef boost::unordered_map<std::string, Behavior*> BehaviorMap;

			/** map (hash table) that contains the factory behavior objects by name */
			BehaviorMap behaviors;

			/** single access point to singleton \b factory */
			static BehaviorFactory * factory;

		public:
			BehaviorFactory(void); /**< default constructor */
			virtual ~BehaviorFactory(void); /**< destructor */

			/** Create a new instance of the specified behavior
			* @pre the specified name must already have a registered behavior with the 
			* same name in the factory.
			* @post the new behavior's state is Behavior::CREATED.
			* @param name the name of the required behavior
			*/
			static Behavior * createBehavior (std::string& name);

			/** register the behavior with the factory so that createbehavior can make
			* a copy. The object that is registered is a copy of the specified behavior object and 
			* its state will be Behavior::FACTORY.
			* The caller is responsible for deleting the specified one.
			* Specifying a name for the second time will result in overwriting the first one.
			* @param behavior the behavior to register.
			* @param name the name for the behavior. The name must be unique
			*/
			static bool registerBehavior (Behavior& behavior, std::string& name);

		private:
			
			static BehaviorFactory * singleton (); /**< @internal */
		};

	}
}

#endif // __entity_behaviorfactory_h //
